﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using AutoMapper;
using DHM.IRepository;
using DHM.IService;
using DHM.Model;
using DHM.Model.DTO;
using DHM.Service;
using DHM.WXMiniProgram.Utility.APIResult;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Caching.Memory;

namespace DHM.WXMiniProgram.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    [Authorize]
    public class UserViewsController : ControllerBase
    {
        /// <summary>
        /// 用户浏览量
        /// </summary>
        private readonly IUserViewsService _iUserViewsService;
        /// <summary>
        /// 用户评论数
        /// </summary>
        private readonly IUserCommentService _userCommentService;
        /// <summary>
        /// 用户点赞数
        /// </summary>
        private readonly IUserLikesService _userLikesService;
        private readonly IMemoryCache _memoryCache;
        public UserViewsController(IUserViewsService userViewsService, IUserCommentService userCommentService,
            IUserLikesService userLikesService, IMemoryCache cache)
        {
            this._iUserViewsService = userViewsService;
            this._userLikesService = userLikesService;
            this._userCommentService = userCommentService;
            this._memoryCache = cache;
        }
        /// <summary>
        /// 一次性获取各个模块的用户社交数据
        /// </summary>
        /// <returns></returns>
        [HttpGet("GetUserView")]
        public async Task<APIResult> GetUserViewByCommentModule([FromServices] IMapper iMapper)
        {
            UserViews u = null;
            if (!_memoryCache.TryGetValue<UserViews>("UserViews", out var us))
            {
                Task<UserViews> userViews = _iUserViewsService.FindFirst<UserViews>();
                us = await _memoryCache.GetOrCreateAsync<UserViews>("UserViews",
                    entry =>
                    {
                        entry.AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(2);
                        entry.RegisterPostEvictionCallback((key, obj, reason, state) =>
                        {
                            if (reason == EvictionReason.Expired)
                            {
                                _iUserViewsService.UpdateAsync(us);
                                _memoryCache.Remove("UserViews");
                            }
                        });

                        return userViews;
                    });
                u = us;
            }
            else
            {
                _memoryCache.TryGetValue<UserViews>("UserViews", out u);
            }
            //获取各个模块的用户浏览量
            // var userViewsCount = iMapper.Map<UserViewsDtoOutPut> (await _iUserViewsService.FindFirst<UserViews> ());

            var userViewsCount = iMapper.Map<UserViewsDtoOutPut>(u);
            // var userViewsCount = iMapper.Map<UserViewsDtoOutPut>(u);

            //获取用户针对每个模块的评论量
            var userCommentCount = await GetUserCommentCountsByModule();

            //获取用户针对每个模块的用户点赞量
            var userLikesCount = await GetUserLikesCountByModule();

            dynamic result = new
            {
                viewsCount = userViewsCount,
                likesCount = userLikesCount,
                commentCount = userCommentCount
            };
            return APIResultHelper.Success(result);
        }
        /// <summary>
        /// 设置用户针对各个模块的点击量
        /// </summary>
        /// <returns></returns>
        [HttpPost("SetUserClick")]
        public async Task<APIResult> SetUserClickByCache([FromForm] CommentModule commentModule)
        {
            //var result = await SetViewCount(commentModule);

            var result = await SetViewCountByMomoryCache(commentModule);

            if (result != null)
            {
                return APIResultHelper.Success($"{commentModule.ToString()}点击量设置成功");
            }
            else
            {
                return APIResultHelper.Error($"{commentModule.ToString()}点击量设置失败");
            }
        }

        #region 获取各个模块用户浏览数据
        /// <summary>
        /// 获取y用户针对每个模块的点赞量
        /// </summary>
        /// <typeparam name="UserComment"></typeparam>
        /// <returns></returns>
        private async Task<ModuleLikesCount> GetUserLikesCountByModule()
        {
            var swfLikes =
                await _userLikesService.GetModuleCount(x => x.SWF_Like == true);

            var mhcLikes =
                await _userLikesService.GetModuleCount(x => x.MHC_Like == true);

            var szyzLikes =
                await _userLikesService.GetModuleCount(x => x.SDMS_Like == true);

            var sdmsLikes =
                await _userLikesService.GetModuleCount(x => x.SDMS_Like == true);

            var arLikes =
                await _userLikesService.GetModuleCount(x => x.AR_Like == true);

            var moduleLike = new ModuleLikesCount
            {
                SWF_Likes = swfLikes,
                MHC_Likes = mhcLikes,
                SZYZ_Likes = szyzLikes,
                SDMS_Likes = sdmsLikes,
                AR_Likes = arLikes
            };
            return moduleLike;
        }

        private async Task<ModuleCommentCount> GetUserCommentCountsByModule()
        {
            var swfLikes =
                await _userCommentService.GetModuleCount(x => x.CommentModule.Equals(CommentModule.SWF));

            var mhcLikes =
                await _userCommentService.GetModuleCount(x => x.CommentModule.Equals(CommentModule.MHC));

            var szyzLikes =
                await _userCommentService.GetModuleCount(x => x.CommentModule.Equals(CommentModule.SZYZ));

            var sdmsLikes =
                await _userCommentService.GetModuleCount(x => x.CommentModule.Equals(CommentModule.SDMS));

            var arLikes =
                await _userCommentService.GetModuleCount(x => x.CommentModule.Equals(CommentModule.AR));

            var moduleComment = new ModuleCommentCount
            {
                SWF_Comments = swfLikes,
                MHC_Comments = mhcLikes,
                SZYZ_Comments = szyzLikes,
                SDMS_Comments = sdmsLikes,
                AR_Comments = arLikes
            };
            return moduleComment;
        }
        /// <summary>
        /// 获取各个模块的用户点击量
        /// </summary>
        /// <param name="commentModule"></param>
        /// <returns></returns>
        private async Task<UserViews> SetViewCount(CommentModule commentModule)
        {

            UserViews userViews = await _iUserViewsService.FindFirst<UserViews>();

            if (userViews == null)
            {
                var views = new UserViews { SZYZ_Views = 0, SWF_Views = 0, MHC_Views = 0, SDMS_Views = 0, AR_Views = 0 };
                userViews = views;
                await _iUserViewsService.AddAsync(views);
            }

            // UserViews result = new UserViews();
            switch (commentModule)
            {
                case CommentModule.SZYZ:
                    ++userViews.SZYZ_Views;
                    break;
                case CommentModule.SWF:
                    ++userViews.SWF_Views;
                    break;
                case CommentModule.MHC:
                    ++userViews.MHC_Views;
                    break;
                case CommentModule.SDMS:
                    ++userViews.SDMS_Views;
                    break;
                case CommentModule.AR:
                    ++userViews.AR_Views;
                    break;
                default:
                    break;
            }
            await _iUserViewsService.UpdateAsync(userViews);
            return userViews;
        }
        /// <summary>
        /// 使用缓存
        /// </summary>
        /// <param name="commentModule"></param>
        /// <returns></returns>
        private async Task<UserViews> SetViewCountByMomoryCache(CommentModule commentModule)
        {
            if (!_memoryCache.TryGetValue<UserViews>("UserViews", out var us))
            {
                Task<UserViews> userViews = _iUserViewsService.FindFirst<UserViews>();
                us = await _memoryCache.GetOrCreateAsync<UserViews>("UserViews",
                    entry =>
                    {
                        entry.AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(2);
                        entry.RegisterPostEvictionCallback((key, obj, reason, state) =>
                        {
                            if (reason == EvictionReason.Expired)
                            {
                                _iUserViewsService.UpdateAsync(us);
                                _memoryCache.Remove("UserViews");
                            }
                        });
                        return userViews;
                    });
                if (us != null) ViewCountSelfPlus(us, commentModule);
            }
            else
            {
                us = _memoryCache.Get<UserViews>("UserViews");
                if (us != null) ViewCountSelfPlus(us, commentModule);
            }
            return us;
        }

        /// <summary>
        /// 用户浏览量自加
        /// </summary>
        /// <param name="us"></param>
        /// <param name="commentModule"></param>
        private void ViewCountSelfPlus(UserViews us, CommentModule commentModule)
        {
            switch (commentModule)
            {
                case CommentModule.SZYZ:
                    ++us.SZYZ_Views;
                    break;
                case CommentModule.SWF:
                    ++us.SWF_Views;
                    break;
                case CommentModule.MHC:
                    ++us.MHC_Views;
                    break;
                case CommentModule.SDMS:
                    ++us.SDMS_Views;
                    break;
                case CommentModule.AR:
                    ++us.AR_Views;
                    break;
                default:
                    break;
            }
            if (_memoryCache.TryGetValue<UserViews>("UserViews", out UserViews u))
            {
                u = us;
            }
        }
        /// <summary>
        /// 每个模块用户留言量
        /// </summary>
        private struct ModuleCommentCount
        {
            public int MHC_Comments { get; set; }
            public int SWF_Comments { get; set; }

            public int SZYZ_Comments { get; set; }

            public int AR_Comments { get; set; }

            public int SDMS_Comments { get; set; }
        }
        /// <summary>
        /// 各个模块用户的点赞量
        /// </summary>
        private struct ModuleLikesCount
        {
            public int MHC_Likes { get; set; }
            public int SWF_Likes { get; set; }

            public int SZYZ_Likes { get; set; }

            public int AR_Likes { get; set; }

            public int SDMS_Likes { get; set; }
        }

        #endregion

    }
}